package cn.dinxian.activiti.demo2.controller;

import cn.dinxian.activiti.demo2.constent.NumberConstants;
import cn.dinxian.activiti.demo2.tool.PageUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;

import cn.dinxian.entity.CommonResult;
import cn.dinxian.entity.MyProcessInstance;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import java.util.Set;
import java.util.stream.Collectors;
import org.activiti.engine.RuntimeService;

import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;


import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author dingxian
 * @Title:
 * @param:
 * @return:
 * @Date 2023/2/27 12:26
 * @Description:
 */
@RestController
@RequestMapping("runtime-provider")
@Slf4j
@ComponentScan("cn.dinxian.activiti")
public class MyRuntimeServiceController {
  @Autowired
  RuntimeService runtimeService;

  //@Autowired
  //ProcessRuntime processRuntime;

  /**
   *  创建实例
   * @param id 部署的名称
   * @return 返回实例的名称
   */
  @GetMapping("/startProcess/{id}")
  public CommonResult<String> startProcessbyID(@PathVariable("id") String id){
    Map<String,Object> map= new HashMap<>();
    
     ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(id,map);
    final String processInstanceId = processInstance.getProcessInstanceId();
  
    return  new CommonResult<String>(200,JSONObject.toJSONString(processInstanceId));
  }

  @PostMapping( "/createProcessInstance")
  public CommonResult<MyProcessInstance> createProcessInstance(@RequestBody MyProcessInstance dto) {
    ProcessInstance processInstance = this.runtimeService.createProcessInstanceBuilder()
        .processDefinitionKey(dto.getProcessDefinitionKey())
        .businessKey(dto.getBusinessKey())
        .name(dto.getName())
        .variables(dto.getVariable())
        .start();
    dto.setId(processInstance.getId());
     return new CommonResult<MyProcessInstance>(200,"创建成功",dto);
  }

  @PostMapping( "/ProcessInstanceQuery")
  public CommonResult<MyProcessInstance> processInstanceQuery(@RequestBody MyProcessInstance dto){
    ProcessInstanceQuery processInstanceQuery = this.buildProcessInstanceQuery(dto);
    dto.setCurrent(NumberConstants.Num.ONE);
    dto.setPageSize(NumberConstants.Num.EIGHT);
    IPage page = PageUtils.getPage(processInstanceQuery, dto);
    //  page = page.convert(u -> {
    //  MyProcessInstance v = new MyProcessInstance();
    //  BeanUtils.copyProperties(u, v);
    //  return v;
    //});
    page.setRecords(this.assembleProcessInstance(page.getRecords()));
    final MyProcessInstance myProcessInstance = (MyProcessInstance) page.getRecords().get(0);

    return new CommonResult<MyProcessInstance>(200,"yes",myProcessInstance) ;
    
  }
  
  @PostMapping( "/processInstanceQueryList")
  public CommonResult<List<MyProcessInstance>> processInstanceQueryList(@RequestBody MyProcessInstance dto){
    ProcessInstanceQuery processInstanceQuery = this.buildProcessInstanceQuery(dto);
    dto.setCurrent(NumberConstants.Num.ONE);
    dto.setPageSize(NumberConstants.Num.EIGHT);
    IPage page = PageUtils.getPage(processInstanceQuery, dto);
    List<MyProcessInstance> list = this.assembleProcessInstance(page.getRecords());
     return new CommonResult<List<MyProcessInstance>>(200,null,list);
  }

  @PostMapping( "/getvarious")
  public CommonResult<MyProcessInstance> getvarious( @RequestBody MyProcessInstance dto){

    String result=null;
    try {
      result= runtimeService.getVariable(dto.getId(), dto.getName()).toString();
    }
    catch (Exception e){
      return null;
    }
     return new CommonResult<MyProcessInstance>(200,null, MyProcessInstance.builder()
         .processInstanceDescription(result)
         .build());
  }
  
  
  
  private List<MyProcessInstance> assembleProcessInstance(List<ProcessInstance> processInstances) {
    if (ObjectUtils.isEmpty(processInstances)) {
      return Lists.emptyList();
    }
    return processInstances.stream().map(this::assembleProcessInstance).collect(Collectors.toList());
  }
  private MyProcessInstance assembleProcessInstance(ProcessInstance processInstance) {
   
    return MyProcessInstance.builder()
        .processDefinitionId(processInstance.getProcessDefinitionId())
        .processDefinitionName(processInstance.getProcessDefinitionName())
        .processDefinitionKey(processInstance.getProcessDefinitionKey())
        .processDefinitionVersion(processInstance.getProcessDefinitionVersion())
        .deploymentId(processInstance.getDeploymentId())
        .businessKey(processInstance.getBusinessKey())
        .isSuspended(processInstance.isSuspended())
        .processVariables(processInstance.getProcessVariables())
        .tenantId(processInstance.getTenantId())
        .processInstanceName(processInstance.getName())
        .processInstanceDescription(processInstance.getDescription())
        .localizedName(processInstance.getLocalizedName())
        .localizedDescription(processInstance.getLocalizedDescription())
        .startTime(processInstance.getStartTime())
        .startUserId(processInstance.getStartUserId())
        .appVersion(processInstance.getAppVersion())
        .executionIsEnded(processInstance.isEnded())
        .activityId(processInstance.getActivityId())
        .processInstanceId(processInstance.getProcessInstanceId())
        .parentExecutionId(processInstance.getParentId())
        .superExecutionId(processInstance.getSuperExecutionId())
        .rootProcessInstanceId(processInstance.getRootProcessInstanceId())
        .parentProcessInstanceId(processInstance.getParentProcessInstanceId())
        .id(processInstance.getId())
        .build();
    //return MyProcessInstance.builder()
    //    .id(processInstance.getId())
    //    .variable(processInstance.getVariable())
    //    .businessKey(processInstance.getBusinessKey())
    //    .name(processInstance.getName())
    //    .processDefinitionKey(processInstance.getProcessDefinitionKey())
    //    .processInstanceId(processInstance.getProcessInstanceId())
    //    .singleOrList(processInstance.gets)
    //    .deploymentId(processInstance.getDeploymentId())
    //    .processInstanceBusinessKey(processInstance.getProcessInstanceBusinessKey())
    //    .processInstanceName(processInstance.getProcessInstanceName())
    //    .processInstanceNameLike(processInstance.getProcessInstanceNameLike())
    //    .startTime(processInstance.getStartTime())
    //    .endTime(processInstance.getEndTime())
    //    .isSuspended(processInstance.getIsSuspended())
    //    .build();
  }
  private ProcessInstanceQuery buildProcessInstanceQuery(MyProcessInstance request) {
    ProcessInstanceQuery processInstanceQuery = this.runtimeService.createProcessInstanceQuery();
    if (ObjectUtils.isNotEmpty(request.getProcessInstanceId())) {
      processInstanceQuery.processInstanceId(request.getProcessInstanceId());
    }

    if (ObjectUtils.isNotEmpty(request.getProcessInstanceBusinessKey())) {
      processInstanceQuery.processInstanceBusinessKey(request.getProcessInstanceBusinessKey());
    }
    if (ObjectUtils.isNotEmpty(request.getProcessDefinitionKey())) {
      processInstanceQuery.processDefinitionKey(request.getProcessDefinitionKey());
    }
    if (ObjectUtils.isNotEmpty(request.getProcessInstanceName())) {
      processInstanceQuery.processInstanceName(request.getProcessInstanceName());
    }
    if (ObjectUtils.isNotEmpty(request.getProcessInstanceNameLike())) {
      processInstanceQuery.processInstanceNameLike(request.getProcessInstanceNameLike());
    }
    if (ObjectUtils.isNotEmpty(request.getStartTime())) {
      processInstanceQuery.startedAfter(request.getStartTime());
    }
    if (ObjectUtils.isNotEmpty(request.getEndTime())) {
      processInstanceQuery.startedBefore(request.getEndTime());
    }
    if (ObjectUtils.isNotEmpty(request.getIsSuspended()) && request.getIsSuspended()) {
      processInstanceQuery.suspended();
    }
    if (ObjectUtils.isNotEmpty(request.getIsSuspended()) && !request.getIsSuspended()) {
      processInstanceQuery.active();
    }    
    if (ObjectUtils.isNotEmpty(request.getIdList()) ) {
      final Set<String> collect = request.getIdList().stream().collect(Collectors.toSet());
      processInstanceQuery.processInstanceIds(collect);
    }
    
    return processInstanceQuery;
  }
}
